package com.dx.mes.service.tool.service;

import com.dx.common.table.ppt.*;
import com.dx.mes.common.dao.*;
import com.dx.mes.common.transcoder.util.*;
import com.dx.mes.facade.tool.service.IFdpaplyreService;
import com.dx.mes.facade.tool.tx.Fdpaplyre.*;
import org.apache.commons.lang.StringUtils;
import org.hibernate.LockMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.dx.mes.common.bean.def.GenericDef.*;

@Service("fdpaplyreService")
@SuppressWarnings({"unchecked"})
public class FdpaplyreService implements IFdpaplyreService {
    private static final String TX_NAME = T_FDPAPLYRE;
    private LogUtils logUtils;

    @Autowired
    private IRetRepairOrderDao retRepairOrderDao;
    @Override
    public String subMainProc(String evt_no, String strInTrx) {
        AppContext.clear();
        AppContext.setCurrServiceName(FdpaplyreService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(FdpaplyreService.class);
        logUtils.info("[InTrx:" + strInTrx + "]");
        String strOutTrx = "";
        FdpaplyreI inTrx = new FdpaplyreI();
        FdpaplyreO outTrx = new FdpaplyreO();
        outTrx.setTrx_id(TX_NAME);
        outTrx.setType_id(TRX_OUT);
        outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));

        try {
            inTrx = JacksonUtil.fromJson(strInTrx, FdpaplyreI.class);
            char action_flg = inTrx.getAction_flg().charAt(0);
            switch (action_flg) {
                case ACTION_FLG_QUERY:
                    queryByConditionFnc(inTrx, outTrx);//查询维修单
                    break;
                case ACTION_FLG_ADD://新增维修单
                    addFnc(inTrx, outTrx);
                    break;
                case 'U'://修改维修单
                    updateFnc(inTrx, outTrx);
                    break;
                case ACTION_FLG_DELETE:
                    deleteFnc(inTrx, outTrx);
                    break;
                case 'R'://维修
                    repairFnc(inTrx, outTrx);
                    break;
                case 'C'://维修完成
                    compFnc(inTrx, outTrx);
                    break;
                case 'Z'://维修单转单
                    changeFnc(inTrx, outTrx);
                    break;
                default:
                    errActionFnc(outTrx);
            }
            if (RETURN_CODE_OK.equals(outTrx.getRtn_code())) {
                retRepairOrderDao.flushCurSession();
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        } catch (Exception ex) {
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            outTrx.setRtn_mesg(ex.toString());
            logUtils.error(Util.stackTraceToString(ex));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        } finally {
            strOutTrx = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + strOutTrx + "]");
        }

        return strOutTrx;
    }



    public void queryByConditionFnc(FdpaplyreI inTrx, FdpaplyreO outTrx) {
        List<FdpaplyreOA> oaryList = new ArrayList<FdpaplyreOA>();
        String hql = " From Ret_repair_order where 1 = 1";
        if(!StringUtils.isEmpty(inTrx.getRepair_order_id())){
            hql += " and repair_order_id = '" + inTrx.getRepair_order_id() +"'";
        }
        if(!StringUtils.isEmpty(inTrx.getResponsible_usr())){
            hql += " and responsible_usr = '" + inTrx.getResponsible_usr() + "'";
        }
        if(!StringUtils.isEmpty(inTrx.getFab_id_fk())){
            hql += " and fab_id_fk = '" + inTrx.getFab_id_fk() + "'";
        }
        if(!StringUtils.isEmpty(inTrx.getLine_id_fk())){
            hql += " and line_id_fk = '" + inTrx.getLine_id_fk() +"'";
        }
        if(!StringUtils.isEmpty(inTrx.getTool_id_fk())){
            hql += " and tool_id_fk = '" + inTrx.getTool_id_fk() +"'";
        }

        List<Ret_repair_order>  retRepairOrderList = retRepairOrderDao.find(hql);
        if(retRepairOrderList != null && retRepairOrderList.size() > 0){
            for(Ret_repair_order ret_repair_order : retRepairOrderList){
                FdpaplyreOA oary = new FdpaplyreOA();
                oary.setCrt_timestamp(ret_repair_order.getCrt_timestamp());
                oary.setRepair_order_id(ret_repair_order.getRepair_order_id());
                oary.setFab_id_fk(ret_repair_order.getFab_id_fk());
                oary.setLine_id_fk(ret_repair_order.getLine_id_fk());
                oary.setTool_id_fk(ret_repair_order.getTool_id_fk());
                oary.setError_dsc(ret_repair_order.getError_dsc());
                oary.setRepair_beg_timestamp(ret_repair_order.getRepair_beg_timestamp());
                oary.setRepair_end_timestamp(ret_repair_order.getRepair_end_timestamp());
                oary.setDowntime(ret_repair_order.getDowntime());
                oary.setTech_confirm_flg(ret_repair_order.getTech_confirm_flg());
                oary.setQual_confirm_flg(ret_repair_order.getQual_confirm_flg());
                oary.setProd_confirm_flg(ret_repair_order.getProd_confirm_flg());
                oary.setError_analysis(ret_repair_order.getError_analysis());
                oary.setRepair_dsc(ret_repair_order.getRepair_dsc());
                oary.setRepair_result(ret_repair_order.getRepair_result());
                oary.setEqt_confirmer(ret_repair_order.getEqt_confirmer());
                oary.setTech_confirmer(ret_repair_order.getTech_confirmer());
                oary.setQa_confirmer(ret_repair_order.getQa_confirmer());
                oary.setPro_confirmer(ret_repair_order.getPro_confirmer());
                oary.setResponsible_usr(ret_repair_order.getResponsible_usr());
                oary.setTransfer_note(ret_repair_order.getTransfer_note());
                oary.setRepair_stat( ret_repair_order.getRepair_stat());
                oaryList.add(oary);
            }
        }
        outTrx.setOary(oaryList);
        outTrx.setTbl_cnt(oaryList.size());
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    public void addFnc(FdpaplyreI inTrx, FdpaplyreO outTrx){
            Timestamp currentTime = Util.getCurrentTimestamp();
            List<FdpaplyreIA> list =  inTrx.getIary();
            String retPairOrdeId = generateCode("R");
            FdpaplyreIA fdpaplyreIA = list.get(0);
            //根据工单代码获取工单信息
            Ret_repair_order ret_repair_order = retRepairOrderDao.getWithLock(retPairOrdeId, LockMode.UPGRADE);
            if(ret_repair_order != null){
                outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR) + "");
                outTrx.setRtn_mesg("已存在维修单" + retPairOrdeId);
                return;
            }else{
                Ret_repair_order retRepairOrder = new Ret_repair_order();
                retRepairOrder.setRepair_order_id(retPairOrdeId);
                retRepairOrder.setResponsible_usr(inTrx.getResponsible_usr());
                retRepairOrder.setFab_id_fk(inTrx.getFab_id_fk());
                retRepairOrder.setLine_id_fk(inTrx.getLine_id_fk());
                retRepairOrder.setTool_id_fk(inTrx.getTool_id_fk());
                retRepairOrder.setAssistants(fdpaplyreIA.getAssistants());
                retRepairOrder.setTech_confirm_flg(fdpaplyreIA.getTech_confirm_flg());
                retRepairOrder.setQual_confirm_flg(fdpaplyreIA.getQual_confirm_flg());
                retRepairOrder.setProd_confirm_flg(fdpaplyreIA.getProd_confirm_flg());
                retRepairOrder.setDowntime(fdpaplyreIA.getDowntime());
                retRepairOrder.setError_dsc(fdpaplyreIA.getError_dsc());
                retRepairOrder.setError_analysis(fdpaplyreIA.getError_analysis());
                retRepairOrder.setRepair_dsc(fdpaplyreIA.getRepair_dsc());
                retRepairOrder.setRepair_result(fdpaplyreIA.getRepair_result());
                retRepairOrder.setEqt_confirmer(fdpaplyreIA.getEqt_confirmer());
                retRepairOrder.setTech_confirmer(fdpaplyreIA.getTech_confirmer());
                retRepairOrder.setQa_confirmer(fdpaplyreIA.getQa_confirmer());
                retRepairOrder.setPro_confirmer(fdpaplyreIA.getPro_confirmer());
                retRepairOrder.setTransfer_note(fdpaplyreIA.getTransfer_note());
                retRepairOrder.setRepair_stat(WO_STATUS_WAIT);
                retRepairOrder.setCrt_usr(inTrx.getEvt_usr());
                retRepairOrder.setCrt_timestamp(Util.getCurrentTimestamp());
                retRepairOrder.setEvt_usr(inTrx.getEvt_usr());
                retRepairOrder.setEvt_timestamp(Util.getCurrentTimestamp());
                retRepairOrderDao.save(retRepairOrder);

                List<FdpaplyreOA> oaryList = new ArrayList<>();
                FdpaplyreOA oary = new FdpaplyreOA();
                oary.setRepair_order_id(retRepairOrder.getRepair_order_id());
                oary.setResponsible_usr(retRepairOrder.getResponsible_usr());
                oary.setFab_id_fk(retRepairOrder.getFab_id_fk());
                oary.setLine_id_fk(retRepairOrder.getLine_id_fk());
                oary.setTool_id_fk(retRepairOrder.getTool_id_fk());
                oary.setAssistants(retRepairOrder.getAssistants());
                oary.setTech_confirm_flg(retRepairOrder.getTech_confirm_flg());
                oary.setQual_confirm_flg(retRepairOrder.getQual_confirm_flg());
                oary.setProd_confirm_flg(retRepairOrder.getProd_confirm_flg());
                oary.setDowntime(retRepairOrder.getDowntime());
                oary.setError_dsc(retRepairOrder.getError_dsc());
                oary.setError_analysis(retRepairOrder.getError_analysis());
                oary.setRepair_dsc(retRepairOrder.getRepair_dsc());
                oary.setRepair_result(retRepairOrder.getRepair_result());
                oary.setEqt_confirmer(retRepairOrder.getEqt_confirmer());
                oary.setTech_confirmer(retRepairOrder.getTech_confirmer());
                oary.setQa_confirmer(retRepairOrder.getQa_confirmer());
                oary.setPro_confirmer(retRepairOrder.getPro_confirmer());
                oary.setCrt_timestamp(retRepairOrder.getCrt_timestamp());
                oary.setRepair_stat(retRepairOrder.getRepair_stat());
                oaryList.add(oary);
                outTrx.setOary(oaryList);
            }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }


    public void updateFnc(FdpaplyreI inTrx, FdpaplyreO outTrx){
        Timestamp currentTime = Util.getCurrentTimestamp();
        List<FdpaplyreIA> list =  inTrx.getIary();
        FdpaplyreIA fdpaplyreIA = list.get(0);
            //根据工单代码获取工单信息
            Ret_repair_order ret_repair_order = retRepairOrderDao.getWithLock(inTrx.getRepair_order_id(), LockMode.UPGRADE);
            if(ret_repair_order == null){
                outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR) + "");
                outTrx.setRtn_mesg("维修单" + inTrx.getRepair_order_id()+"不存在");
                return;
            }else{
                if(!StringUtils.isEmpty(inTrx.getResponsible_usr())){
                    ret_repair_order.setResponsible_usr(inTrx.getResponsible_usr());
                }
                if(!StringUtils.isEmpty(inTrx.getFab_id_fk())){
                    ret_repair_order.setFab_id_fk(inTrx.getFab_id_fk());
                }
                if(!StringUtils.isEmpty(inTrx.getLine_id_fk())){
                    ret_repair_order.setLine_id_fk(inTrx.getLine_id_fk());
                }
                if(!StringUtils.isEmpty(inTrx.getTool_id_fk())){
                    ret_repair_order.setTool_id_fk(inTrx.getTool_id_fk());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getAssistants())){
                    ret_repair_order.setAssistants(fdpaplyreIA.getAssistants());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getTech_confirm_flg())){
                    ret_repair_order.setTech_confirm_flg(fdpaplyreIA.getTech_confirm_flg());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getQual_confirm_flg())){
                    ret_repair_order.setQual_confirm_flg(fdpaplyreIA.getQual_confirm_flg());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getProd_confirm_flg())){
                    ret_repair_order.setProd_confirm_flg(fdpaplyreIA.getProd_confirm_flg());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getError_dsc())){
                    ret_repair_order.setError_dsc(fdpaplyreIA.getError_dsc());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getError_analysis())){
                    ret_repair_order.setError_analysis(fdpaplyreIA.getError_analysis());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getRepair_dsc())){
                    ret_repair_order.setRepair_dsc(fdpaplyreIA.getRepair_dsc());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getRepair_result())){
                    ret_repair_order.setRepair_result(fdpaplyreIA.getRepair_result());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getEqt_confirmer())){
                    ret_repair_order.setEqt_confirmer(fdpaplyreIA.getEqt_confirmer());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getTech_confirmer())){
                    ret_repair_order.setTech_confirmer(fdpaplyreIA.getTech_confirmer());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getQa_confirmer())){
                    ret_repair_order.setQa_confirmer(fdpaplyreIA.getQa_confirmer());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getPro_confirmer())){
                    ret_repair_order.setPro_confirmer(fdpaplyreIA.getPro_confirmer());
                }
                if(!StringUtils.isEmpty(fdpaplyreIA.getTransfer_note())){
                    ret_repair_order.setTransfer_note(fdpaplyreIA.getTransfer_note());
                }
                ret_repair_order.setEvt_usr(inTrx.getEvt_usr());
                ret_repair_order.setEvt_timestamp(Util.getCurrentTimestamp());
                retRepairOrderDao.update(ret_repair_order);
            }
            List<FdpaplyreOA> oaryList = new ArrayList<>();
            FdpaplyreOA oary = new FdpaplyreOA();
            oary.setRepair_order_id(ret_repair_order.getRepair_order_id());
            oary.setResponsible_usr(ret_repair_order.getResponsible_usr());
            oary.setFab_id_fk(ret_repair_order.getFab_id_fk());
            oary.setLine_id_fk(ret_repair_order.getLine_id_fk());
            oary.setTool_id_fk(ret_repair_order.getTool_id_fk());
            oary.setAssistants(ret_repair_order.getAssistants());
            oary.setTech_confirm_flg(ret_repair_order.getTech_confirm_flg());
            oary.setQual_confirm_flg(ret_repair_order.getQual_confirm_flg());
            oary.setProd_confirm_flg(ret_repair_order.getProd_confirm_flg());
            oary.setDowntime(ret_repair_order.getDowntime());
            oary.setError_dsc(ret_repair_order.getError_dsc());
            oary.setError_analysis(ret_repair_order.getError_analysis());
            oary.setRepair_dsc(ret_repair_order.getRepair_dsc());
            oary.setRepair_result(ret_repair_order.getRepair_result());
            oary.setEqt_confirmer(ret_repair_order.getEqt_confirmer());
            oary.setTech_confirmer(ret_repair_order.getTech_confirmer());
            oary.setQa_confirmer(ret_repair_order.getQa_confirmer());
            oary.setPro_confirmer(ret_repair_order.getPro_confirmer());
        oaryList.add(oary);
        outTrx.setOary(oaryList);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }



    public void deleteFnc(FdpaplyreI inTrx, FdpaplyreO outTrx) {
        List<FdpaplyreIA> iary = inTrx.getIary();
        String repairOrderId = inTrx.getRepair_order_id();
        Ret_repair_order ret_repair_order = retRepairOrderDao.get(repairOrderId);
        if (ret_repair_order == null) {
            outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
            outTrx.setRtn_mesg("record not found");
            return;
        }
        if (WO_STATUS_WAIT.equals(ret_repair_order.getRepair_stat())) {
            retRepairOrderDao.delete(ret_repair_order);
        } else {
            outTrx.setRtn_code(E_FDPAPLYWO_STAT_ERROR + "");
            outTrx.setRtn_mesg("维修单[" + repairOrderId + "]的状态为" + ret_repair_order.getRepair_stat() + ",不可删除！");
            return;
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }


    public void repairFnc(FdpaplyreI inTrx, FdpaplyreO outTrx) {
        String repairOrderId = inTrx.getRepair_order_id();
        Ret_repair_order ret_repair_order = retRepairOrderDao.get(repairOrderId);
        if(ret_repair_order == null){
            outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
            outTrx.setRtn_mesg("record not found");
            return;
        }else{
            if(ret_repair_order.getRepair_stat().equals(WO_STATUS_WAIT)){
                ret_repair_order.setRepair_stat("INPR");
            }else{
                outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
                outTrx.setRtn_mesg("维修单状态不是WAIT，不可再执行维修");
                return;
            }
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }


    public void compFnc(FdpaplyreI inTrx, FdpaplyreO outTrx) {
        String repairOrderId = inTrx.getRepair_order_id();
        Ret_repair_order ret_repair_order = retRepairOrderDao.get(repairOrderId);
        if(ret_repair_order == null){
            outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
            outTrx.setRtn_mesg("record not found");
            return;
        }else{
            if(ret_repair_order.getRepair_stat().equals("INPR")){
                ret_repair_order.setRepair_stat("COMP");
            }else{
                outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
                outTrx.setRtn_mesg("维修单状态不是INPR，不可再结束维修");
                return;
            }
        }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    public void changeFnc(FdpaplyreI inTrx, FdpaplyreO outTrx){
        String repairOrderId = inTrx.getRepair_order_id();
        String responsePerA = inTrx.getResponsible_usr();
        String responsePerB = inTrx.getResponsible_usrB();
        Ret_repair_order ret_repair_order = retRepairOrderDao.get(repairOrderId);
        if(ret_repair_order == null){
            outTrx.setRtn_code(E_FDPAPLYWO_NOT_FOUND + "");
            outTrx.setRtn_mesg("维修单不存在");
            return;
        }else{
            ret_repair_order.setResponsible_usr(responsePerB);
            ret_repair_order.setEvt_usr(inTrx.getEvt_usr());
            ret_repair_order.setEvt_timestamp(Util.getCurrentTimestamp());
            ret_repair_order.setEvt_cate("RECG");
            retRepairOrderDao.update(ret_repair_order);

        }
        List<FdpaplyreOA> oaryList = new ArrayList<>();
        FdpaplyreOA oary = new FdpaplyreOA();
        oary.setRepair_order_id(ret_repair_order.getRepair_order_id());
        oary.setResponsible_usr(ret_repair_order.getResponsible_usr());
        oary.setFab_id_fk(ret_repair_order.getFab_id_fk());
        oary.setLine_id_fk(ret_repair_order.getLine_id_fk());
        oary.setTool_id_fk(ret_repair_order.getTool_id_fk());
        oary.setAssistants(ret_repair_order.getAssistants());
        oary.setTech_confirm_flg(ret_repair_order.getTech_confirm_flg());
        oary.setQual_confirm_flg(ret_repair_order.getQual_confirm_flg());
        oary.setProd_confirm_flg(ret_repair_order.getProd_confirm_flg());
        oary.setDowntime(ret_repair_order.getDowntime());
        oary.setError_dsc(ret_repair_order.getError_dsc());
        oary.setError_analysis(ret_repair_order.getError_analysis());
        oary.setRepair_dsc(ret_repair_order.getRepair_dsc());
        oary.setRepair_result(ret_repair_order.getRepair_result());
        oary.setEqt_confirmer(ret_repair_order.getEqt_confirmer());
        oary.setTech_confirmer(ret_repair_order.getTech_confirmer());
        oary.setQa_confirmer(ret_repair_order.getQa_confirmer());
        oary.setPro_confirmer(ret_repair_order.getPro_confirmer());
        oaryList.add(oary);
        outTrx.setOary(oaryList);
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }



    public void errActionFnc(FdpaplyreO outTrx) {
        outTrx.setRtn_code("0000009");
        outTrx.setRtn_mesg("Invalid Action_flg");
    }

    public String generateCode(String woCate) {
        String code = "";
        int i = 0;
        char[] Digit = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        Timestamp currentTime = Util.getCurrentTimestamp();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        String time = sf.format(currentTime);
        String timeCode = String.join("", time.split("-")).substring(2);
        String cate = woCate.substring(0, 1);

        String likeCode = "L" + cate + timeCode + "A";
        String hql = "From Ret_repair_order where repair_order_id like '%" + likeCode + "%'";
        List<Ret_repair_order> retRepairOrderList = retRepairOrderDao.find(hql);
        if (retRepairOrderList.size() > 0) {
            List<Byte> bytes = new ArrayList<Byte>();
            for (Ret_repair_order ret_repair_order : retRepairOrderList) {
                String repairOrderId = ret_repair_order.getRepair_order_id();
                char ch = repairOrderId.charAt(repairOrderId.length() - 1);
                byte b = (byte) ch;
                bytes.add(b);
            }
            byte mByte = Collections.max(bytes);
            char mch = (char) mByte;

            if (mch == Digit[8]) {
                mByte = 65;
                mch = (char) mByte;
                code = likeCode + mch;
                return code;
            }
            mByte++;
            mch = (char) mByte;
            code = likeCode + mch;
            return code;
        } else {
            i = 0;
            code = likeCode + Digit[i];
            return code;
        }
    }


}
